home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
- /*
- *
- * Rotate.c
- *
- * Part of the "Curve Demo"
- * by Howard Look for Silicon Graphics
- *
- * June, 1989
- *
- * This file contains the routines used for rotating the view volume.
- *
- */
-
-
- #include <stdio.h>
- #include <gl.h>
- #include <device.h>
- #include <math.h>
- #include "curve.h"
- #include "event.h"
-
-
- /* Prototypes */
- void rotate_view_volume(void);
- void update_rotation(void);
- Boolean within_cube(void);
-
- extern void fake_view_volume(void);
- extern void set_three_d_view(void);
-
- /* Just your basic, plain, vanilla identity matrix */
- Matrix identity_matrix =
- { {1.0,0.0,0.0,0.0},
- {0.0,1.0,0.0,0.0},
- {0.0,0.0,1.0,0.0},
- {0.0,0.0,0.0,1.0}
- };
-
-
- /*
- * This matrix get successively updated as the user rotates the view
- * volume. It represents the transformation to rotate the view volume
- * (and the curve within it) from whatever the current transformation
- * is to the appropriate rotated view.
- */
- Matrix rotate_matrix =
- { {1.0,0.0,0.0,0.0},
- {0.0,1.0,0.0,0.0},
- {0.0,0.0,1.0,0.0},
- {0.0,0.0,0.0,1.0}
- };
-
-
- /* About the window... */
- extern int origin_x, origin_y, size_x, size_y;
-
-
- /*
- * Routine to rotate the view volume using a trackball-like interface
- * to the mouse.
- *
- * Called whevever the middle mouse button is pressed AND we are in 3D
- * display mode. Program flow remains here until the middle mouse is
- * released. Successively updates the rotation matrix then calls the
- * drawing routine.
- *
- * How the trackball works:
- * If the user clicks and drags within the bounds of the view volume,
- * the volume is rotated about the world x and y axes, following the
- * motion of the mouse. If the user clicks outside the view volume,
- * then rotation follows the mouse about the z axis.
- *
- * Why the rotation matrix works:
- * Normally, all transformation take place relative to an objects own
- * coordinate system. Therefore when the object rotates, so does its
- * own coordinate system.
- *
- * In this program, we wish for the rotation of the view volume to
- * take place relative to the fixed world coordinate system. That is,
- * when the user drags the mouse in the x direction, we want the
- * rotation to take place about the world y axis, not about the
- * object's y axis (because after a zillion rotations, God only knows
- * where the object's coordinate system is pointing).
- *
- * The rotation matrx is a 'pure' matrix in that it merely accumulates
- * the rotations we wish to make. By starting each time with the
- * identity matrix, computing the rotation for this iteration, and
- * multiplying it to the rotation matrix, we have a transformation
- * matrix that describes pure rotation from the world coordinate
- * system, which does not move.
- *
- * Thanks Thant.
- */
-
-
- /* Scaled mouse values (-1.0 to 1.0) */
- static float last_x, last_y;
-
- /* Did the user click inside the view volume ? */
- static Boolean inside;
-
- extern Boolean rotating;
-
- void rotate_view_volume(void)
- {
- long mx, my;
-
- mx = getvaluator(MOUSEX);
- my = getvaluator(MOUSEY);
-
- inside = within_cube();
-
- /* Scale mouse values to square around -1.0 to 1.0 */
- last_x = 2.0*((Coord)(mx - origin_x)/size_x - 0.5);
- last_y = 2.0*((Coord)(my - origin_y)/size_y - 0.5);
-
- qdevice(MOUSEX);
- qdevice(MOUSEY);
-
- rotating = TRUE;
- }
-
-
- void update_rotation(void)
- {
- float new_x, new_y, dx, dy, dz;
- long mx, my;
-
- mx = getvaluator(MOUSEX);
- my = getvaluator(MOUSEY);
- dx = dy = dz = 0.0; /* Mouse rotation, in degrees */
-
- if (inside)
- {
- /* rotate about x-y */
-
- /* sweeping the mouse across the width of the screen,
- left to right causes a positive 90 degree rotation
- about the y axis, etc. */
- new_x = 2.0*((Coord)(mx - origin_x)/size_x - 0.5);
- /* mouse y rotation, in degrees */
- dy = 45.0*(new_x-last_x);
- last_x = new_x;
-
- new_y = 2.0*((Coord)(my - origin_y)/size_y - 0.5);
- /* mouse x rotation, in degrees */
- dx = -45.0*(new_y-last_y);
- last_y = new_y;
- }
- else
- {
- /* rotate about z */
-
- new_x = 2.0*((Coord)(mx - origin_x)/size_x - 0.5);
- new_y = 2.0*((Coord)(my - origin_y)/size_y - 0.5);
-
- dz = (fatan2(new_y, new_x) - fatan2(last_y, last_x)) RAD;
-
- last_x = new_x;
- last_y = new_y;
- }
-
- /* compute and accumulate the rotation matrix */
- pushmatrix();
- loadmatrix(identity_matrix);
- rot(dx, 'x');
- rot(dy, 'y');
- rot(dz, 'z');
- multmatrix(rotate_matrix);
- getmatrix(rotate_matrix);
- popmatrix();
- }
-
-
-
-
-
- /*
- * Returns TRUE is x and y (in screen coords) are within the boundries
- * of the view volume.
- */
- Boolean within_cube(void)
- {
- long result;
- short buffer;
-
- picksize(1,1);
-
- initnames();
- pick(&buffer, 1);
- set_three_d_view();
- multmatrix(rotate_matrix);
- fake_view_volume();
- result = endpick(&buffer);
-
- return(buffer == 1);
- }
-
-
-
-
-